package com.lambo.maven.core.utils.superHttp.core;

import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.lambo.maven.core.utils.superHttp.SHttp;
import com.lambo.maven.core.utils.superHttp.SHttpException;
import com.lambo.maven.core.utils.superHttp.entity.HttpResult;
import com.lambo.maven.core.utils.superHttp.entity.SHttpConfig;
import com.lambo.maven.core.utils.superHttp.utils.SHttpUtil;

/**
 * 默认请求入口实现
 * SHttpCore
 */
public class SHttpCoreDefault implements SHttpCore {

    private static Logger logger = LoggerFactory.getLogger(SHttpCoreDefault.class);

    private static SHttpCore instance = new SHttpCoreDefault();

    public static SHttpCore me() {
        return instance;
    }

    public static SHttpCore byConfig(SHttpConfig config) {
        Class<?> clazz = config.getShttpCore();
        if(clazz == SHttpCoreDefault.class) {
            return me();
        } else if (clazz == null) {
            return me();
        } else {
            try {
                Debug.info("newInstance SHttpCore");
				return (SHttpCore) clazz.newInstance();
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
        }
    }

    // 核心方法
    public HttpResult corePost(SHttp shttp, String url, HttpEntity entity, Map<String, String> header, String encoding){
		
        HttpPost httpPost = new HttpPost(url);
        CloseableHttpResponse httpResponse = null;
		try {
            httpPost.setEntity(entity);
			// 设置请求器的配置
            httpPost.setConfig(shttp.getProxyRequestConfig());
            if(header != null) {
                for(String key : header.keySet()) {
                    String value = header.get(key);
                    httpPost.addHeader(key, value);
                }
			}
			shttp.initHttpRequest(httpPost);
            if(shttp.getContext() == null) {
                httpResponse = shttp.getProxyHttpClient().execute(httpPost);
            } else {
                httpResponse = shttp.getProxyHttpClient().execute(httpPost, shttp.getContext());
            }

            shttp.initHttpResponse(httpResponse);
            HttpEntity resEntity = httpResponse.getEntity();
            HttpResult result = new HttpResult(resEntity, httpPost, httpResponse);
            return result;
            
		} catch (Exception e) {
            SHttpUtil.closeHttp(httpPost, httpResponse);
            logger.error("请求" + url + "异常");
			throw err(e);
		}
    }

    public HttpResult coreGet(SHttp shttp, String url, String content, Map<String, String> header, String encoding) {
        HttpResult result = coreGetResult(shttp, url, content, header, encoding);
        try {
            return result;
        } catch (Exception e) {
            logger.error("请求" + url + "异常");
			throw err(e);
        }
    }

	public HttpResult coreGetResult(SHttp shttp, String url, String content, Map<String, String> header, String encoding) {
		String requestUrl;

        if(StringUtils.isBlank(content)) {
            requestUrl = url;
        } else {
            requestUrl = url + "?" + content;
        }

        HttpGet httpGet = new HttpGet(requestUrl);
        CloseableHttpResponse httpResponse = null;
        
        try {
            httpGet.setConfig(shttp.getProxyRequestConfig());
            if(header != null) {
                for(String key : header.keySet()) {
                    String value = header.get(key);
                    httpGet.addHeader(key, value);
                }
            }
            Debug.info("header", header);
			shttp.initHttpRequest(httpGet);
            if(shttp.getContext() == null) {
                httpResponse = shttp.getProxyHttpClient().execute(httpGet);
            } else {
                httpResponse = shttp.getProxyHttpClient().execute(httpGet, shttp.getContext());
            }
            shttp.initHttpResponse(httpResponse);
            
            HttpEntity entity = httpResponse.getEntity();

            HttpResult result = new HttpResult(entity, httpGet, httpResponse);
            return result;
            
		} catch (Exception e) {
            logger.error("请求" + url + "异常");
            SHttpUtil.closeHttp(httpGet, httpResponse);
			throw err(e);
		}
    }

    public static final String ERR_TIMEOUT = "请求超时，请稍后再试";
    public static final String ERR_FAIL = "请求失败，请稍后再试";
    public static final String ERR_UNKOWN_HOST = "请求未知Host异常";
    
    /**
     * 对异常解析后返回自定义异常
     * @param e
     * @return
     */
    public static SHttpException err(Exception e) {
        String message;
        boolean custom = true;
        if(e instanceof UnknownHostException) {
            message = ERR_UNKOWN_HOST;
        } else if(e instanceof SocketTimeoutException) {
            message = ERR_TIMEOUT;
        } else {
            message = ERR_FAIL;
            custom = false;
        }
        if(!custom) {
            logger.error("http请求异常" + e.getMessage(), e);
        }
        SHttpException se = new SHttpException(message, e);
        se.setCustom(custom);
        return se;
    }
}